/*
 * ESProtectedPink.cs
 *
 * Created on January 3, 2008, 11:39 PM
 *
 * Copyright (C) 2007-2008  Hylke van der Schaaf
 * Copyright (C) 2010       Mathijs Miermans
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, in version 3 of the License.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */


using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;


namespace HexTD
{
	public class ESProtectedPink : EnemySpriteBase
	{

		private int prevPaintTime;
#if PORT
		private Shape[] bodyShapes;
		private Shape[] shieldShapesTop;
		private Shape[] shieldShapesBottom;
#endif
		private int shieldStep = 0;
#if PORT
		private Brush shieldStroke;
#endif
		private Color shieldColor = Color.White;
#if PORT
		private Brush bodyStroke;
#endif
		private int bodyStep = 0;
		private Color bodyColor = new Color(255, 255, 180, 180);
		private int[,] damage;
		private int damagePointer = 0;
		private int[] damageTotals;
		private bool damaged = false;
		private static string infostring =
				"<h1>Protected Pink</h1>" +
				"<p>" +
				"This pink menace has adaptive shielding technology. It's shield will counter the color that has done the most damage in the last few seconds.<br>" +
				"Either take it out with one shot, or attack it with multiple colored towers at the same time." +
				"</p>";

		/**
		 * Creates a new instance of ESProtectedPink
		 */
		public ESProtectedPink(Game game)
			: base(game, "Protected Pink")
		{
			this.damageColor = COLOR.OTHER;
			this.damageColorAnti = COLOR.OTHER;
		}

		public void doInit(Context context, int path, float delay, long health, int price, Size s)
		{
			this.damage = new int[3, 40];
			this.damageTotals = new int[3];
			base.doInit(context, path, delay, health, price, s);
		}

		public string getInfostring()
		{
			return infostring +
					"<p>" + base.getInfostring() + "</p>";
		}

		public void doTick(int gameTime)
		{
			this.damageTotals[0] += this.damage[0, this.damagePointer];
			this.damageTotals[1] += this.damage[1, this.damagePointer];
			this.damageTotals[2] += this.damage[2, this.damagePointer];

			if (this.damaged)
			{
				this.checkTotals();
			}

			this.damagePointer++;
			if (this.damagePointer >= this.damage.GetLength(1))
			{
				this.damagePointer = 0;
			}
			this.damageTotals[0] -= this.damage[0, this.damagePointer];
			this.damageTotals[1] -= this.damage[1, this.damagePointer];
			this.damageTotals[2] -= this.damage[2, this.damagePointer];
			this.damage[0, this.damagePointer] = 0;
			this.damage[1, this.damagePointer] = 0;
			this.damage[2, this.damagePointer] = 0;
			base.doTick(gameTime);
		}

		private void checkTotals()
		{
			if (this.damageTotals[0] > this.damageTotals[1])
			{
				// GREEN or YELLOW
				if (this.damageTotals[0] > this.damageTotals[2])
				{
					// GREEN
					this.damageColor = COLOR.RED;
					this.damageColorAnti = COLOR.GREEN;
					this.shieldColor = Color.Red;
				}
				else
				{
					// YELLOW
					this.damageColor = COLOR.BLUE;
					this.damageColorAnti = COLOR.YELLOW;
					this.shieldColor = Color.Blue;
				}
			}
			else
			{
				// RED or YELLOW
				if (this.damageTotals[1] > this.damageTotals[2])
				{
					// RED
					this.damageColor = COLOR.GREEN;
					this.damageColorAnti = COLOR.RED;
					this.shieldColor = Color.Green;
				}
				else if (this.damageTotals[1] == this.damageTotals[2])
				{
					// RED
					this.damageColor = COLOR.OTHER;
					this.damageColorAnti = COLOR.OTHER;
					this.shieldColor = Color.White;
				}
				else
				{
					// YELLOW
					this.damageColor = COLOR.BLUE;
					this.damageColorAnti = COLOR.YELLOW;
					this.shieldColor = Color.Blue;
				}
			}
		}

		public void doDamage(int damage, COLOR c)
		{
			switch (c)
			{
				case COLOR.GREEN:
					this.damaged = true;
					this.damage[0, this.damagePointer] += damage;
					break;
				case COLOR.RED:
					this.damaged = true;
					this.damage[1, this.damagePointer] += damage;
					break;
				case COLOR.YELLOW:
					this.damaged = true;
					this.damage[2, this.damagePointer] += damage;
					break;
			}
			base.doDamage(damage, c);
		}

		public void resetScale()
		{
#if PORT
			base.resetScale();
			Cache cache = this.context.getCache();
			float scale = this.context.paintScale * this.size.scaleMod;

			if (cache.hasShapeArr("ESPPShapes" + this.size.letter)) {
				this.bodyShapes = cache.getShapeArr("ESPPShapes" + this.size.letter);
				this.shieldShapesTop = cache.getShapeArr("ESPPShieldTop" + this.size.letter);
				this.shieldShapesBottom = cache.getShapeArr("ESPPShieldBot" + this.size.letter);
			} else {
				this.bodyShapes = new Shape[20];
				double dr = 0.5 * Math.PI / this.bodyShapes.length;
				double r = 0;
				for (int i = 0; i < this.bodyShapes.length; i++) {

					float[,] points = {
						{+scale * 0.2f * ((float) Math.Sin(+r)), +scale * 0.2f * ((float) Math.Cos(+r))},
						{+scale * 0.2f * ((float) Math.Cos(+r)), -scale * 0.2f * ((float) Math.Sin(+r))},
						{-scale * 0.2f * ((float) Math.Sin(+r)), -scale * 0.2f * ((float) Math.Cos(+r))},
						{-scale * 0.2f * ((float) Math.Cos(+r)), +scale * 0.2f * ((float) Math.Sin(+r))}
					};
					this.bodyShapes[i] = Geometry.coordsToGeneralPath(points, true);
					r += dr;
				}
				cache.putShapeArr("ESPPShapes" + this.size.letter, this.bodyShapes);

				this.shieldShapesTop = new Shape[20];
				this.shieldShapesBottom = new Shape[20];
				float shieldH = 0.3f * this.context.paintScale * this.size.scaleMod;
				float shieldRot;
				float shieldW;
				float front;
				int shieldO;
				for (int i = 0; i < this.shieldShapesTop.length; i++) {
					shieldRot = (float) Math.PI / this.shieldShapesTop.length * i;
					shieldW = shieldH * (float) Math.Sin(-shieldRot);
					front = (float) Math.Cos(shieldRot);
					if ((shieldW < 0 && front < 0) || (shieldW > 0 && front > 0)) {
						shieldO = -1;
					} else {
						shieldO = 1;
					}
					shieldW = Math.Abs(shieldW);
					this.shieldShapesBottom[i] = new Arc2D.Double(-shieldW, -shieldH, shieldW * 2, shieldH * 2, shieldO * 90, 180, Arc2D.OPEN);
					this.shieldShapesTop[i] = new Arc2D.Double(-shieldW, -shieldH, shieldW * 2, shieldH * 2, -shieldO * 90, 180, Arc2D.OPEN);
				}
				cache.putShapeArr("ESPPShieldTop" + this.size.letter, this.shieldShapesTop);
				cache.putShapeArr("ESPPShieldBot" + this.size.letter, this.shieldShapesBottom);
			}
			this.bodyStroke = new Brush(3.0f * this.context.strokeScale, Brush.CAP_ROUND, Brush.JOIN_ROUND);
			this.shieldStroke = new Brush(2.0f * this.context.strokeScale, Brush.CAP_ROUND, Brush.JOIN_ROUND);
#endif
		}

		public override void Draw(GameTime gameTime)
		{
#if PORT
			if (this.inactive || this.dead) {
				this.prevPaintTime = gameTime;
			} else {
				Brush defaultStroke = g2.getStroke();
				this.bodyStep += gameTime - this.prevPaintTime;
				while (this.bodyStep >= this.bodyShapes.Length) {
					this.bodyStep = 0;
				}
				this.shieldStep += gameTime - this.prevPaintTime;
				if (this.shieldStep >= this.shieldShapesTop.Length) {
					this.shieldStep = 0;
				}
				this.prevPaintTime = gameTime;

				RotateTransform saveXform = g2.getTransform();
				g2.transform(atTranslate);

				if (this.shielded) {
					this.paintShield_bottom(g2);
				}
				this.paintHealthLine(g2);

				g2.setStroke(this.shieldStroke);
				g2.setColor(this.shieldColor);
				g2.draw(this.shieldShapesBottom[this.shieldStep]);

				g2.setColor(this.bodyColor);
				g2.setStroke(this.bodyStroke);
				g2.draw(this.bodyShapes[this.bodyStep]);

				g2.setStroke(this.shieldStroke);
				g2.setColor(this.shieldColor);
				g2.draw(this.shieldShapesTop[this.shieldStep]);

				g2.setTransform(saveXform);

				if (this.shielded) {
					g2.transform(atTranslate);
					this.paintShield_top(g2);
					g2.setTransform(saveXform);
				}
			
				base.paintSelected(g2);

				g2.setStroke(defaultStroke);
			}
#endif
		}
	}
}